﻿@inject IJSRuntime JSRuntime

<div class="markdown-body" @ref="markdownContainer"></div>
<a target="_blank"></a>

@code {
    private ElementReference markdownContainer;

    [Parameter] public string html { get; set; } = "";

    [Parameter] public string BaseUrl { get; set; } = "";

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!string.IsNullOrEmpty(html))
        {
            await JSRuntime.InvokeVoidAsync("insertHtml", markdownContainer, html, BaseUrl);
        }
    }

}

<script>
    window.insertHtml = function (element, html, imageUrl) {


        const md = markdownit({
            html: true,
            linkify: true,
            typographer: true
        })
        mermaid.initialize({startOnLoad: true});

        md.use(markdownItAnchor);

        md.core.ruler.push('baseurl', (state) => {
            const baseUrl = `/${imageUrl}/`;

            function rewrite(tokens) {
                for (const token of tokens) {
                    if (token.type === 'image') {
                        if (!(imageUrl === undefined || imageUrl === '')) {
                            for (const attr of token.attrs) {
                                if (attr[0] === 'src') {
                                    attr[1] = baseUrl + attr[1];
                                }
                            }
                        }
                        token.attrs.push(['class', 'img-fluid'])
                    }

                    if (token.type === 'link_open') {
                        token.attrs.push(['class', 'apple-link'])
                        token.attrs.push(['target', '_blank'])
                    }
                    // Process recursively
                    if (token.children !== null) {
                        rewrite(token.children);
                    }
                }
            }

            rewrite(state.tokens);
        });

        md.use(markdownitContainer, 'warning', {
            validate: function (params) {
                return params.trim().match(/^warning\s+(.*)$/);
            },
            render: function (tokens, idx) {
                const m = tokens[idx].info.trim().match(/^warning\s+(.*)$/);
                if (tokens[idx].nesting === 1) {
                    return `<div class="warning custom-block"><p style="font-weight: bold">${md.utils.escapeHtml(m[1])}</p>\n`;
                } else {
                    return '</div>\n';
                }
            }
        })

        md.use(markdownitContainer, 'danger', {
            validate: function (params) {
                return params.trim().match(/^danger\s+(.*)$/);
            },
            render: function (tokens, idx) {
                const m = tokens[idx].info.trim().match(/^danger\s+(.*)$/);
                if (tokens[idx].nesting === 1) {
                    return `<div class="danger custom-block"><p style="font-weight: bold">${md.utils.escapeHtml(m[1])}</p>\n`;
                } else {
                    return '</div>\n';
                }
            }
        })

        md.use(markdownitContainer, 'tip', {
            validate: function (params) {
                return params.trim().match(/^tip\s+(.*)$/);
            },
            render: function (tokens, idx) {
                const m = tokens[idx].info.trim().match(/^tip\s+(.*)$/);
                if (tokens[idx].nesting === 1) {
                    return `<div class="tip custom-block"><p style="font-weight: bold">${md.utils.escapeHtml(m[1])}</p>\n`;
                } else {
                    return '</div>\n';
                }
            }
        })

        element.innerHTML = md.render(html);
        //Prism.highlightAll();
        mermaid.init(undefined, document.querySelectorAll('.language-mermaid'));
        // // 如果使用 Prism.js
        setTimeout(() => {
            Prism.highlightAll();
        }, 50); // 根据需要调整延迟时间
    }
</script>

<link rel="stylesheet" href="markdown.css"/>